from pathlib import Path
from typing import List, Optional


class ExclusiveHdmiGuard:
    def __init__(self, enable: bool) -> None:
        self.enable = enable
        self._prev_printk: Optional[str] = None
        self._vtcon_paths: List[Path] = []

    def __enter__(self):
        if not self.enable:
            return self
        self._lower_kernel_console_verbosity()
        self._unbind_fbcon_from_vt()
        return self

    def __exit__(self, exc_type, exc, tb):
        if not self.enable:
            return False
        self._restore_vtcon_binding()
        self._restore_kernel_console_verbosity()
        return False

    def _lower_kernel_console_verbosity(self) -> None:
        printk = Path("/proc/sys/kernel/printk")
        try:
            if printk.exists():
                self._prev_printk = printk.read_text().strip()
                printk.write_text("1\n")
        except Exception:
            # 无权限或内核不支持，忽略
            pass

    def _restore_kernel_console_verbosity(self) -> None:
        if self._prev_printk is None:
            return
        printk = Path("/proc/sys/kernel/printk")
        try:
            printk.write_text(self._prev_printk + "\n")
        except Exception:
            pass

    def _unbind_fbcon_from_vt(self) -> None:
        vt_root = Path("/sys/class/vtconsole")
        if not vt_root.exists():
            return
        for vt in sorted(vt_root.glob("vtcon*")):
            name_file = vt / "name"
            bind_file = vt / "bind"
            try:
                name_text = name_file.read_text().strip().lower()
                if "frame buffer" in name_text or "framebuffer" in name_text:
                    bind_file.write_text("0\n")
                    self._vtcon_paths.append(vt)
            except Exception:
                continue

    def _restore_vtcon_binding(self) -> None:
        for vt in self._vtcon_paths:
            bind_file = vt / "bind"
            try:
                bind_file.write_text("1\n")
            except Exception:
                continue


